package util.ir;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;

import org.apache.lucene.analysis.WhitespaceAnalyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;

import util.io.TextFileLoader;

import com.jcraft.jsch.HASH;

public class SearchTopics {
	
	
	
	public static void multiFieldSearch(String question, String field[],
			String visualizedfield, String index,
			Hashtable<String, Float> hash, int max) throws ParseException,
			CorruptIndexException, IOException {

		String querystr = question;
		StandardAnalyzer analyzer = new StandardAnalyzer();

		MultiFieldQueryParser parser = new MultiFieldQueryParser(field,
				analyzer);

		Query q = parser.parse(question);

		IndexSearcher searcher = new IndexSearcher(index);
		// ScoreDoc[] hits = collector.topDocs().scoreDocs;
		System.out.println("Searching for: " + question);

		Hits hits = searcher.search(q);
		System.out.println("> "); // start with '> '

		int end = Math.min(hits.length(), max);

		for (int i = 0; i < end; i++) {
	
			Document doc = hits.doc(i);
			List ff = doc.getFields();
			
			for(int j =0; j < ff.size(); j++){
				
				System.out.println(ff.get(i));
			}
			String name = doc.get(visualizedfield);
			if (name != null) {
				// System.out.println((i + 1) + ". " + name + " (score " +
				// hits.score(i) + ", docid 000000");
				if (hash.containsKey(name)) {

					Float f = hash.get(name);
					f = f + hits.score(i);

				} else {

					hash.put(name, hits.score(i));
				}

			} else {
				System.out
						.println((i + 1) + ". " + "No name for this document");
			}
		}

		System.out.println("\n" + hits.length() + " matching documents");

		searcher.close();

	}
	
	public static void getTopicFeatures(Hashtable<String, Float> scores, Hashtable<String, Float> features) {

		float total = 0;
		
		Enumeration<String> keys = scores.keys();
		while(keys.hasMoreElements()){
			
			String topic = keys.nextElement();
			Float score = scores.get(topic);
			
			if(topic.toLowerCase().contains("international")){
				
				continue;
			}
			
			features.put(topic, score);
			
			total+=score;
			
		}
		
		 /* 
		 * Normalize scores
		 * 
		 * 
		 */

		Enumeration<String> keys1 = features.keys();

		while (keys1.hasMoreElements()) {

			String topic = keys1.nextElement();
		//System.out.println("adentro");
			features.put(topic, features.get(topic) / total);
		}
		
		
		//System.out.println("termino");

	}
	
	
	public static void generateFeatures(String index,String path, String field, int max){
		
		
		TextFileLoader reader = new TextFileLoader(path);
		while(reader.hasNext()){
			String line[]= reader.next();
			String query =line[0];
			String original =query;
			query = query.replaceAll("_", " ");
			
			if(line.length==0) continue;
			if(line[0].equals("")) continue;
			
			String view =field;
			
			Hashtable<String,Float> hash= new Hashtable<String,Float>();
		
		//	multiFieldSearch(query,fields, view, index,hash,max);
			try {
				standardSearch(query, "text",view,index,hash,max);
			} catch (CorruptIndexException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} 
			
			Hashtable<String, Float> topics= new Hashtable<String,Float>();
			getTopicFeatures(hash,topics);
			
			printTopicFeatures(original,topics,field);
			
		}
		
	}
	
	public static  void printTopicFeatures(String query, Hashtable<String, Float> topics, String level){
		
		Enumeration<String> keys = topics.keys();
		
		while(keys.hasMoreElements()){
			
			String topic = keys.nextElement();
			
			float score = topics.get(topic);
			
			
			System.out.println(query +"\t"+topic  + "\t"+ score );
		}
		
	}
	
	
	public static void standardSearch(String question, String field,
			String visualizedfield, String index,
			Hashtable<String, Float> hash, int max) throws ParseException,
			CorruptIndexException, IOException {

		question = question.trim();
		if(question.equals("")) return;
		
		String querystr = question;
		WhitespaceAnalyzer analyzer = new WhitespaceAnalyzer();

		Query q = new QueryParser(field, analyzer).parse(querystr);
		IndexSearcher searcher = new IndexSearcher(index);
		// ScoreDoc[] hits = collector.topDocs().scoreDocs;
		//System.out.println("Searching for: " + q.toString(field));

		Hits hits = searcher.search(q);
		//System.out.println("> "); // start with '> '

		int end = Math.min(hits.length(), max);

		for (int i = 0; i < end; i++) {

			Document doc = hits.doc(i);
			String name = doc.get(visualizedfield);
			name = name.toLowerCase();
			if (name != null) {
			//	System.out.println((i + 1) + ". " + name + " (score "+ hits.score(i) + ", docid 000000");
				if (hash.containsKey(name)) {

					Float f = hash.get(name);
					f = f + hits.score(i);
					hash.put(name,f);
				} else {

					hash.put(name, hits.score(i));
				}

			} else {
				//System.out.println((i + 1) + ". " + "No name for this document");
			}
		}

		//System.out.println("\n" + hits.length() + " matching documents");

		searcher.close();

	}

	public static void main(String args[]) {
		
		String index = "/home/sergio/data/indexes/dmoz_topics_plus/";
		String query_tags="/home/sergio/data/graph/query_tags_plus1.txt";
		String evaluation_path="aol";
		String field="topic2";
		
		
		
		if(args.length>1){
			
			
			index=args[0];
			query_tags=args[1];
			evaluation_path=args[2];
			
			
		}
		
		
		try {
			
			
		
			searchTopics(index,query_tags,evaluation_path,field,100);
		} catch (CorruptIndexException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	
	
	public static void readQueries(String path, HashSet<String> queries) {

		int _eval_query = 6;

		TextFileLoader reader = new TextFileLoader(path);
		while (reader.hasNext()) {
			String line[] = reader.next();
			if (line.length > _eval_query + 1) {
				String query = line[_eval_query];
				queries.add(query);
			}

		}

	}
	
	public static String buildQueryString(String query , ArrayList<QueryTag> q_model){
		
		StringBuffer a=new StringBuffer(query);
		int query_limit=50;
		int booleans=0;
		for(int i =0; q_model!=null && i < q_model.size(); i++){
			
			String tag= q_model.get(i).tag;
			int freq= q_model.get(i).freq;
			if(freq<2)continue;
			
			for(int j=0; j<freq && j <18 && booleans<query_limit; j++){
				booleans++;
				a.append(tag.replaceAll("_", " ") + " ");
			//	System.out.println("concatenando");
			}
			
		//System.out.println("adentro");	
		}
	//	System.out.println("salio");
		return a.toString();
		}
	
	public static void getQueryTopics(String index,String path, String eval_path,
			String field, int max) {

		HashSet<String> queries = new HashSet<String>();
		readQueries(eval_path, queries);
		QueryTagsModel model = new QueryTagsModel(path, queries, 2);

		Iterator<String> iter = queries.iterator();
		while (iter.hasNext()) {
		
			String query = iter.next();
			
			
			System.out.println(query+ "\t"+ query);
			ArrayList<QueryTag> q_model = null;
			if (model.getQueries().containsKey(query)) {

				q_model = model.getQueries().get(query);
			}

			
			if (query.equals(""))
				continue;
			String original = query;
			query = query.replaceAll("_", " ");

			query = buildQueryString(query, q_model);
			
			String view = field;

			Hashtable<String, Float> hash = new Hashtable<String, Float>();

			// multiFieldSearch(query,fields, view, index,hash,max);
			try {
				standardSearch(query, "text", view, index, hash, max);
			} catch (CorruptIndexException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		

			Hashtable<String, Float> topics = new Hashtable<String, Float>();
			getTopicFeatures(hash, topics);

			printTopicFeatures(original, topics, field);
		
		}

	}

	public static void  searchTopics (String index,String query_tags, String evaluation_path, String field , int top) throws CorruptIndexException, ParseException, IOException{
	
	 
	 getQueryTopics(index,query_tags,evaluation_path,field, 100);
		
	
		
		
	}
}
